package com.hy.convenient.tool.xlsx;

import com.hy.convenient.tool.xlsx.interfaces.CheckTypeEnum;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

public class ImportUtil {


    /// 验证行是否是正确的导入文件
    public static void ValidateIsImportFile(LinkedHashMap<String, String> headerRow, Map<String, String> mappings, int sheetNum) {
        String error = "";
        List<String> titleMap = new ArrayList<>();

        for (String key : headerRow.values()) {
            if (!StringUtils.isEmpty(key)) {
                titleMap.add(key.trim());
            }
        }

        for (String currentTitle : titleMap) {
            boolean flag = false;
            for (String item : mappings.values()) {
                flag = false;
                if (item.indexOf(currentTitle) != -1) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                error += "列[" + currentTitle + "]，";
            }
        }

    }


    /**
     * 值向下转型，将不会赋值，向上转型可以 没有对数据进行校验
     *
     * @param map   需要转换的值
     * @param clazz 需要创建的对象
     * @return
     */
    public static <T> T getInstance(Map<String, String> map, Class<T> clazz) {
        Set<String> set = map.keySet();
        Object instance = null;
        try {
            instance = clazz.newInstance();
            Class cla =clazz;
            List<Field> fields = new ArrayList<>() ;
            while (clazz!=null){
                fields.addAll(Arrays.asList(cla .getDeclaredFields()));
                cla = cla.getSuperclass();
                if(cla.getName().contains("Object")){
                    break;
                }
            }
            for (Field f : fields) {
                if (!f.isAnnotationPresent(ImportReflect.class)) {
                    continue;
                }
                ImportReflect keyValue = f.getAnnotation(ImportReflect.class);
                Class clazzName = keyValue.clazzName();
                String value = map.getOrDefault(getKeyValue(keyValue, set), "");
                if (StringUtils.isEmpty(value)) {
                    continue;
                }
                value=    value.trim();
                f.setAccessible(true);
                if (!clazzName.getTypeName().endsWith("Object")) {
                    Method valueOf = clazzName.getMethod("valueOf", String.class);
                    Object obj = valueOf.invoke(clazzName, value);
                    Method b = clazzName.getMethod("getValue");
                    value = b.invoke(obj).toString();
                }
//                boolean 单独转换 是应为 前端提交的值需要转换
                if (f.getGenericType().getTypeName().equals("java.lang.Boolean") || f.getGenericType().getTypeName().equals("boolean")) {
                    value = value.equals("有") || value.equals("是") ? "true" : "false";
                }
               BeanUtils.setProperty(instance, f.getName(), value);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T)instance;
    }


    /**
     * 值向下转型，将不会赋值，向上转型可以 加入校验
     *
     * @param map   需要转换的值
     * @param clazz 需要创建的对象
     * @return
     */
    public static Object getInstance(Map<String, String> map, Class clazz, StringBuilder str, int index) {
        Set<String> set = map.keySet();
        Object instance = null;
        try {
            instance = clazz.newInstance();
            Class cla =clazz;
            List<Field> fields = new ArrayList<>() ;
            while (clazz!=null){
                fields.addAll(Arrays.asList(cla .getDeclaredFields()));
                cla = cla.getSuperclass();
            }
            for (Field f : fields) {
                if (!f.isAnnotationPresent(ImportReflect.class)) {
                    continue;
                }
                ImportReflect keyValue = f.getAnnotation(ImportReflect.class);
                Class clazzName = keyValue.clazzName();
                String cellName = getKeyValue(keyValue, set);
                String value = map.getOrDefault(cellName, "").trim();
                /**
                 * 表示是否坚持数据为null
                 */
                boolean isNull = keyValue.isNull();
                if (StringUtils.isEmpty(value)) {
                    if (isNull) {
//                        由于公司有对应的S听集合 所以后面修改 把所以验证处理后在处理
                        str.append(String.format("第{%s}行,{%S}数据不能为空;", index, cellName));
                    }
                    continue;
                }
                f.setAccessible(true);
                if (!clazzName.getTypeName().endsWith("Object")) {
                    Method valueOf = clazzName.getMethod("valueOf", String.class);
                    Object obj = valueOf.invoke(clazzName, value);
                    Method b = clazzName.getMethod("getValue");
                    value = b.invoke(obj).toString();
                }
//                boolean 单独转换 是应为 前端提交的值需要转换
                if (f.getGenericType().getTypeName().equals("java.lang.Boolean") || f.getGenericType().getTypeName().equals("boolean")) {
                    value = value.equals("有") || value.equals("是") ? "true" : "false";
                }
                CheckTypeEnum valueEnum = keyValue.valueEnum();
                String error = CheckTypeUtil.executeCheck(valueEnum, value, valueEnum == CheckTypeEnum.Date ? keyValue.dataFormatter() : null);
                if (error != null) {
                    str.append(String.format("第{%s}行,{%S}" + error + ";\r\n", index, cellName));
                    continue;
                }
                if (str.length()>0) {
                    continue;
                }
                BeanUtils.setProperty(instance, f.getName(), value);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return instance;
    }

    //    该方法用于多个属性对应一个字段
    private static String getKeyValue(ImportReflect keyValue, Set<String> set) {
        String[] str = keyValue.value();
        for (String s : str) {
            if (set.contains(s)) {
                return s;
            }
        }
        return null;
    }

//    public static EaBuildList ImportExcelByHouse(String token, List<List<LinkedHashMap<String, String>>> list, int neglect, String cantonCode) {
//        EaBuildList buildList = new EaBuildList();
//        List<EaBuild> listEaBuild = new ArrayList<>();
//        //第一层循环工作表 既遍历每一页
//        for (int i = 0; i < list.size() - neglect; i++) {
//            List<LinkedHashMap<String, String>> secondList = list.get(i);
//            LinkedHashMap<String, String> linkedHashMap = secondList.get(0);
//
//            /// 验证行是否是正确的导入文件
//            // com.pengesoft.dwy.utils.ImportUtils.ValidateIsImportFile(linkedHashMap, com.pengesoft.dwy.utils.ImportUtils.getHouseObjStructure(),i);
//
//            //第二层循环每行既遍历每个map
//            list.get(i).remove(list.get(i).get(0));
//            List<HouseRegVo> houseRegModelVosList = list.get(i).stream().map(o -> (HouseRegVo) getInstance(o, HouseRegVo.class)).collect(Collectors.toList());
//            Map<String, List<HouseRegVo>> houseRegModelVoGroup = houseRegModelVosList.stream()
//                    .collect(Collectors.groupingBy(HouseRegVo::getEaBuildName));
//
//            String validate = "^(\\d{2,4}年)?(\\d{1,2})月?$";
//            String validate1 = "^\\d{4}-((0([1-9]))|(1(0|1|2)))$";
//
//            EaOwnerList allOwnerList = new EaOwnerList();
//            int line = 1;
//            String errMsg = "";
//            List<EaHouse> houserList = new ArrayList<>();
//            List<String> propertyIds = new ArrayList<>();
//            //按楼栋分组
//            for (String key : houseRegModelVoGroup.keySet()) {
//                for (HouseRegVo o : houseRegModelVoGroup.get(key)) {
//                    EaBuild build = listEaBuild.stream().filter(h -> h.getEaBuildName().equals(o.getEaBuildName())).findFirst().orElse(null);
//                    //处理建造日期格式
//                    Calendar now = Calendar.getInstance();
//                    String buildAge = now.get(Calendar.YEAR) + "年" + now.get(Calendar.MONTH) + 1 + "月";
//
//                    if (!StringUtils.isEmpty(o.getBuildAge())) {
//                        if (o.getBuildAge().matches(validate) || o.getBuildAge().matches(validate1)) {
//                            buildAge = o.getBuildAge();
//                        }
//                    }
//
//                    if (build == null) {
//                        build = new EaBuild();
//                        build.setEaBuildCode(codeGenerationSvr.BuildEaBuildCode(token, cantonCode));
//                        build.setEaBuildName(o.getEaBuildName());
//                        build.setHouseMade(StringUtils.isEmpty(o.getHouseMadeName()) ? EHouseMades.其他.getValue() : EHouseMades.valueOf(o.getHouseMadeName()).getValue());
//                        build.setBuildAge(buildAge);
//                        EaHouseList eaHouseList = new EaHouseList();
//                        build.setEaHouses(eaHouseList);
//                        //是否独栋在导入的excel表格中没有这一列
//                        //build.setIndepBuild(o.isIndepBuild());
//                        listEaBuild.add(build);
//                    }
//                    EaHouse house = new EaHouse();
//                    house.setEaHouseCode(StringUtils.isEmpty(o.getEaHouseCode()) ? codeGenerationSvr.BuildEaHouseCode(token, cantonCode) : o.getEaHouseCode());
//                    house.setEaBuildName(build.getEaBuildName());
//                    house.setEaUnitName(o.getEaUnitName());
//                    house.setFloor(o.getFloor());
//                    house.setFloorNum(o.getFloorNum());
//                    house.setRoom(o.getRoom());
//                    house.setAddress(o.getAddress());
//                    house.setPoolArea(o.getPoolArea() != null ? o.getPoolArea() : BigDecimal.ZERO);
//                    house.setComprisingArea(o.getComprisingArea() != null ? o.getComprisingArea() : BigDecimal.ZERO);
//                    house.setDimensions(o.getDimensions());
//                    house.setHouseType(EHouseTypes.valueOf(o.getHouseTypeName()).getValue());
//                    house.setSaleStatus(StringUtils.isEmpty(o.getSaleStatusName()) ? ESaleStatus.未设置.getValue() : ESaleStatus.valueOf(o.getSaleStatusName()).getValue());
//                    house.setEaBuildCode(build.getEaBuildCode());
//                    house.setIsHaveElevator(o.isHaveElevator());
//                    FixfAmount normalAmount = new FixfAmount();
//                    normalAmount.setNormalAmount(o.getShouldFundMoney());
//                    house.setShouldFundMoney(normalAmount);
//                    house.setPayCriterion(o.getPayCriterion());
//                    house.setRemarks(o.getRemarks());
//                    house.setPropertyID(o.getPropertyID());
//                    house.setHouseId(o.getHouseId());
//                    //                house.setQiuCode (o.getQiuCode());
//                    house.setRealEstateID(o.getRealEstateID());
//                    house.setBuyMoney(o.getBuyMoney());
////                    house.setRealDimensions (o.getRealDimensions());
////                    house.setRealPoolArea (o.getRealPoolArea()).PsAsDecimal();
//                    // house.setRealComprisingArea (o.getRealComprisingArea()).PsAsDecimal();
//                    house.setContractNumber(o.getContractNumber());
//                    house.setPayArea(o.getPayArea());
//                    normalAmount = new FixfAmount();
//                    normalAmount.setNormalAmount(o.getBalance());
//                    house.setBalance(normalAmount);
//                    //           house.setStandardPrice(o.getStandardPrice());
//                    //          house.setComplementaryPrice (o.getComplementaryPrice());
//                    //        house.setDealPrice (o.getDealPrice());
//
//                    //公房单位处理
////                    if (!StringUtils.isEmpty(o.getPubHouseOrgName()))
////                    {
////                        KeyValueItem pubHouseUnit = housingOrgList.FirstOrDefault(u => u.Value == AnonObj.PubHouseOrgName.Trim());
////                        if (pubHouseUnit == null)
////                            errMsg += "第{line}公有售房单位[{AnonObj.PubHouseOrgName}] 不存在.\r\n";
////                    else
////                        house.setPubHouseOrgCode = pubHouseUnit.Key;
////                    }
//
//                    //重复验证
////                    for (EaBuild item1 : listEaBuild)
////                    {
////                        if( item1.getEaHouses()==null)
////                            continue;
////                        for (EaHouse item2 : item1.getEaHouses())
////                        {
////                            houserList.add(item2);
////                        }
////                    }
//
//                    if (houserList.stream().anyMatch(h -> h.getAddress().equals(house.getAddress())))
//                        errMsg += String.format("第%d行房屋地址【%s】重复.\r\n", line, house.getAddress());
//
//                    if (!StringUtils.isEmpty(o.getPropertyID())) {
//                        propertyIds.add(o.getPropertyID());
//                    }
//
//                    String ownerName = o.getOwnerName();
//                    String ownerNum = o.getCertificateNum();
//                    String ownerPhone = o.getOwnerPhone();
//                    String ownerType = o.getCertificateType();
//
//                    if (house.getSaleStatus() == ESaleStatus.已销售.getValue()
//                            && (StringUtils.isEmpty(ownerName)
//                            || StringUtils.isEmpty(ownerNum)
//                            || StringUtils.isEmpty(ownerType))) {
//                        errMsg += "第{" + line + "}行房屋为已销售状态,请补充完整业主信息.\r\n";
//                    }
//                    String ownMsg = "";
//                    Map<String, Object> map = ControlerUtils.getOwnerByStringb(line, house.getEaHouseCode(), ownerName, ownerNum, ownerPhone, ownerType, "");
//                    house.setEaOwners((EaOwnerList) map.get("EaOwnerList"));
//                    ownMsg = (String) map.get(errMsg);
//
//                    for (EaOwner owner : house.getEaOwners()) {
//                        if (!StringUtils.isEmpty(owner.getOwnerPhone()) && allOwnerList.getItems().stream().filter(item -> item.getOwnerPhone().equals(owner.getOwnerPhone()) && item.getCertificateNum() != owner.getCertificateNum()).count() > 0)
//                            ownMsg += "第{" + line + "}行业主手机号【" + owner.getOwnerPhone() + "】重复.\r\n";
//                    }
//                    allOwnerList.addAll(house.getEaOwners().getItems());
//                    if (!StringUtils.isEmpty(ownMsg)) {
//                        errMsg += ownMsg;
//                    }
//                    build.getEaHouses().add(house);
//                }
//
//                if (!StringUtils.isEmpty(errMsg))
//                    throw new PsCoreRuntimeException(errMsg);
//
//                //与导入的房屋房产证号是否重复
//                Map<String, List<String>> groupByPropertyIds = propertyIds.stream().filter(u -> !StringUtils.isEmpty(u)).collect(Collectors.toList())
//                        .stream().collect(Collectors.groupingBy(x -> x));
//                for (String k1 : groupByPropertyIds.keySet()) {
//                    if (groupByPropertyIds.get(k1).size() > 1)
//                        errMsg += "产权证号【" + k1 + "】重复存在,请检查.\r\n";
//                }
//
//                if (!StringUtils.isEmpty(errMsg))
//                    throw new PsCoreRuntimeException(errMsg);
//
//                //检查同身份证不同姓名
//                Map<String, List<EaOwner>> groupByCertificateNum = allOwnerList.getItems().stream().collect(Collectors.groupingBy(EaOwner::getCertificateNum));
//                for (String k2 : groupByCertificateNum.keySet()) {
//                    if (groupByCertificateNum.get(k2).size() > 1)
//                        errMsg += "身份证号【" + k2 + "】存在不同姓名,请检查.\r\n";
//                }
//                if (!StringUtils.isEmpty(errMsg))
//                    throw new PsCoreRuntimeException(errMsg);
//
//
//                for (EaBuild eaBuild : listEaBuild) {
//                    int totalFloor = 0;
//                    BigDecimal totalArea = new BigDecimal(0);
//                    for (EaHouse house : eaBuild.getEaHouses()) {
//                        if (house.getFloorNum() > totalFloor)
//                            totalFloor = house.getFloorNum();
//                        totalArea = totalArea.add(house.getDimensions());
//                    }
//                    eaBuild.setTotalFloor(totalFloor);
//                    eaBuild.setRegDimensions(totalArea);
//                }
//            }
//
//            //排序 关闭自动排序，增加默认排序和按房屋信息排序 xlang 2018-04-20
//            //foreach (EaBuild build in builds)
//            //{
//            //    EaHouseList houses = new EaHouseList();
//            //    List<EaHouse> hlist = (from EaHouse house in build.EaHouses
//            //                           orderby house.EaBuildName ?? "", house.EaUnitName ?? "", house.FloorNum, house.Room ?? ""
//            //                           select house).ToList();
//            //    houses.AddFrom(hlist);
//            //    build.EaHouses = houses;
//            //}
//            listEaBuild = listEaBuild.stream().sorted(Comparator.comparing(t -> t.getEaBuildName())).collect(Collectors.toList());
//            buildList.addAll(listEaBuild);
//        }
//        return buildList;
//    }
}
